# filepath: d:\CompanyProject\Gitee\DBCompareX\backend\app\models\task_data_sync\setting.py
from datetime import datetime
from typing import List, Dict, Any, Optional
from bson import ObjectId

from ...database.mongodb import (
    task_data_sync_setting_collection,
    task_data_sync_setting_detail_collection,
    task_data_sync_ts_mapping_collection
)

class TaskDataSyncSettingModel:
    """数据同步任务配置模型，处理与MongoDB的交互"""
    
    setting_collection = task_data_sync_setting_collection
    detail_collection = task_data_sync_setting_detail_collection
    mapping_collection = task_data_sync_ts_mapping_collection
    
    @classmethod
    async def create(cls, data: Dict[str, Any], created_by: str = "system") -> Dict[str, Any]:
        """
        创建新的数据同步任务配置
        
        Args:
            data: 包含主表和子表数据的完整配置信息
            created_by: 创建人
            
        Returns:
            创建后的数据同步任务配置信息，包含ID
        """
        # 提取主表和子表数据
        main_data = {
            "task_name": data["task_name"],  # 新增任务名称字段
            "db_info_setting_id": data["db_info_setting_id"],
            "table_name": data["table_name"],
            "query_condition": data["query_condition"],
            "cron_expression": data["cron_expression"],
            "status": data["status"],
            "data_limit": data.get("data_limit"),  # 新增获取数据量字段
            "created_at": datetime.now(),
            "created_by": created_by,
            "updated_at": None,
            "updated_by": None
        }
        
        # 保存主表数据
        result = await cls.setting_collection.insert_one(main_data)
        setting_id = str(result.inserted_id)
        
        # 保存详情表数据
        if "details" in data and data["details"]:
            details = []
            for detail in data["details"]:
                detail_data = {
                    "task_data_sync_setting_id": setting_id,
                    "column_name": detail["column_name"],
                    "comment": detail.get("comment")
                }
                details.append(detail_data)
            
            if details:
                await cls.detail_collection.insert_many(details)
        
        # 保存映射表数据
        if "ts_mapping" in data and data["ts_mapping"]:
            mappings = []
            for mapping in data["ts_mapping"]:
                mapping_data = {
                    "task_data_sync_setting_id": setting_id,
                    "db_info_setting_id": mapping["db_info_setting_id"],
                    "target_column_name": mapping["target_column_name"],
                    "source_table_name": mapping["source_table_name"],
                    "source_column_name": mapping["source_column_name"],
                    "condition": mapping.get("condition"),
                    "priority": mapping["priority"],
                    "target_query_column": mapping.get("target_query_column"),
                    "source_query_column": mapping.get("source_query_column"),
                    "created_at": datetime.now(),
                    "created_by": created_by,
                    "updated_at": None,
                    "updated_by": None
                }
                mappings.append(mapping_data)
            
            if mappings:
                await cls.mapping_collection.insert_many(mappings)
        
        # 获取创建后的完整数据
        return await cls.get_complete_setting(setting_id)
    
    @classmethod
    async def update(cls, id: str, data: Dict[str, Any], updated_by: str = "system") -> Optional[Dict[str, Any]]:
        """
        更新数据同步任务配置
        
        Args:
            id: 数据同步任务配置ID
            data: 更新的数据
            updated_by: 更新人
            
        Returns:
            更新后的数据同步任务配置信息，如果ID不存在则返回None
        """
        # 检查记录是否存在
        existing = await cls.setting_collection.find_one({"_id": ObjectId(id)})
        if not existing:
            return None
            
        # 更新主表数据
        update_data = {}
        if "task_name" in data:
            update_data["task_name"] = data["task_name"]
        if "db_info_setting_id" in data:
            update_data["db_info_setting_id"] = data["db_info_setting_id"]
        if "table_name" in data:
            update_data["table_name"] = data["table_name"]
        if "query_condition" in data:
            update_data["query_condition"] = data["query_condition"]
        if "cron_expression" in data:
            update_data["cron_expression"] = data["cron_expression"]
        if "status" in data:
            update_data["status"] = data["status"]
        if "data_limit" in data:
            update_data["data_limit"] = data["data_limit"]  # 更新获取数据量字段
            
        if update_data:
            update_data["updated_at"] = datetime.now()
            update_data["updated_by"] = updated_by
            
            await cls.setting_collection.update_one(
                {"_id": ObjectId(id)},
                {"$set": update_data}
            )
        
        # 更新详情表数据 (先删除后添加)
        if "details" in data and data["details"] is not None:
            # 删除旧数据
            await cls.detail_collection.delete_many({"task_data_sync_setting_id": id})
            
            # 添加新数据
            if data["details"]:
                details = []
                for detail in data["details"]:
                    detail_data = {
                        "task_data_sync_setting_id": id,
                        "column_name": detail["column_name"],
                        "comment": detail.get("comment")
                    }
                    details.append(detail_data)
                
                if details:
                    await cls.detail_collection.insert_many(details)
        
        # 更新映射表数据 (先删除后添加)
        if "ts_mapping" in data and data["ts_mapping"] is not None:
            # 删除旧数据
            await cls.mapping_collection.delete_many({"task_data_sync_setting_id": id})
            
            # 添加新数据
            if data["ts_mapping"]:
                mappings = []
                for mapping in data["ts_mapping"]:
                    mapping_data = {
                        "task_data_sync_setting_id": id,
                        "db_info_setting_id": mapping["db_info_setting_id"],
                        "target_column_name": mapping["target_column_name"],
                        "source_table_name": mapping["source_table_name"],
                        "source_column_name": mapping["source_column_name"],
                        "condition": mapping.get("condition"),
                        "priority": mapping["priority"],
                        "target_query_column": mapping.get("target_query_column"),
                        "source_query_column": mapping.get("source_query_column"),
                        "created_at": datetime.now(),
                        "created_by": updated_by,
                        "updated_at": None,
                        "updated_by": None
                    }
                    mappings.append(mapping_data)
                
                if mappings:
                    await cls.mapping_collection.insert_many(mappings)
        
        # 获取更新后的完整数据
        return await cls.get_complete_setting(id)
    
    @classmethod
    async def find_by_id(cls, id: str) -> Optional[Dict[str, Any]]:
        """
        根据ID查询数据同步任务配置
        
        Args:
            id: 数据同步任务配置ID
            
        Returns:
            数据同步任务配置信息，如果ID不存在则返回None
        """
        try:
            return await cls.get_complete_setting(id)
        except Exception:
            return None
    
    @classmethod
    async def find_all(cls, query: Dict[str, Any] = None) -> List[Dict[str, Any]]:
        """
        查询所有匹配条件的数据同步任务配置
        
        Args:
            query: 查询条件
            
        Returns:
            数据同步任务配置列表
        """
        if query is None:
            query = {}
        
        # 创建查询条件
        find_query = {}
        
        # 添加可选过滤条件
        if "status" in query and query["status"] is not None:
            find_query["status"] = query["status"]
        if "db_info_setting_id" in query and query["db_info_setting_id"]:
            find_query["db_info_setting_id"] = query["db_info_setting_id"]
        if "table_name" in query and query["table_name"]:
            find_query["table_name"] = {"$regex": query["table_name"], "$options": "i"}
            
        cursor = cls.setting_collection.find(find_query)
        results = await cursor.to_list(length=100)  # 限制最多返回100条记录
        
        # 获取每条记录的完整数据
        complete_results = []
        for result in results:
            setting_id = str(result["_id"])
            complete_data = await cls.get_complete_setting(setting_id)
            if complete_data:
                complete_results.append(complete_data)
            
        return complete_results
        
    @classmethod
    async def get_complete_setting(cls, id: str) -> Dict[str, Any]:
        """
        获取完整的数据同步任务配置（包括主表、详情表和映射表）
        
        Args:
            id: 数据同步任务配置ID
            
        Returns:
            完整的数据同步任务配置信息
        """
        # 获取主表数据
        main_data = await cls.setting_collection.find_one({"_id": ObjectId(id)})
        if not main_data:
            raise ValueError(f"未找到ID为 {id} 的数据同步任务配置")
            
        # 转换ObjectId为字符串
        main_data["_id"] = str(main_data["_id"])
        
        # 获取详情表数据
        detail_cursor = cls.detail_collection.find({"task_data_sync_setting_id": id})
        details = await detail_cursor.to_list(length=None)
        
        # 转换详情数据中的ObjectId为字符串
        for detail in details:
            detail["_id"] = str(detail["_id"])
            
        # 获取映射表数据
        mapping_cursor = cls.mapping_collection.find({"task_data_sync_setting_id": id}).sort("priority", 1)
        mappings = await mapping_cursor.to_list(length=None)
        
        # 转换映射数据中的ObjectId为字符串
        for mapping in mappings:
            mapping["_id"] = str(mapping["_id"])
            
        # 组合完整数据
        main_data["details"] = details
        main_data["ts_mapping"] = mappings
        
        return main_data
    
    @classmethod
    async def find_active_tasks(cls) -> List[Dict[str, Any]]:
        """
        查询所有启用状态的任务
        
        Returns:
            启用状态的数据同步任务配置列表
        """
        return await cls.find_all({"status": 1})
        
    @classmethod
    async def update_status(cls, id: str, status: int, updated_by: str = "system") -> Optional[Dict[str, Any]]:
        """
        仅更新任务状态
        
        Args:
            id: 数据同步任务配置ID
            status: 新的状态值 (0 禁用，1 启用)
            updated_by: 更新人
            
        Returns:
            更新后的数据同步任务配置信息，如果ID不存在则返回None
        """
        # 检查记录是否存在
        existing = await cls.setting_collection.find_one({"_id": ObjectId(id)})
        if not existing:
            return None
            
        # 更新状态字段
        update_data = {
            "status": status,
            "updated_at": datetime.now(),
            "updated_by": updated_by
        }
        
        await cls.setting_collection.update_one(
            {"_id": ObjectId(id)},
            {"$set": update_data}
        )
        
        # 获取更新后的完整数据
        return await cls.get_complete_setting(id)

    @classmethod
    async def delete_by_id(cls, id: str) -> bool:
        """
        根据ID删除数据同步任务配置及相关联数据
        
        Args:
            id: 数据同步任务配置ID
            
        Returns:
            删除成功返回True，否则返回False
        """
        try:
            # 删除主表数据
            result = await cls.setting_collection.delete_one({"_id": ObjectId(id)})
            
            if result.deleted_count > 0:
                # 删除详情表数据
                await cls.detail_collection.delete_many({"task_data_sync_setting_id": id})
                
                # 删除映射表数据
                await cls.mapping_collection.delete_many({"task_data_sync_setting_id": id})
                
                return True
            
            return False
        except Exception:
            return False